import AVFoundation
import Contacts
import CoreBluetooth
import CoreLocation
import EventKit
import Flutter
import Network
import Photos
import SystemConfiguration
import UIKit
import UserNotifications

@main
@objc class AppDelegate: FlutterAppDelegate {
  var flutterEngine: FlutterEngine?
  let locationManager = CLLocationManager()
  let eventStore = EKEventStore()
  let bluetoothManager = CBCentralManager(
    delegate: nil, queue: nil, options: [CBCentralManagerOptionShowPowerAlertKey: false])
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
      // 初始化 Flutter 引擎并启动
      self.flutterEngine = FlutterEngine(name: "eason_flutter_engine")
      self.flutterEngine?.run()
      GeneratedPluginRegistrant.register(with: self.flutterEngine!)

      // 用引擎初始化 FlutterViewController
      let flutterViewController = FlutterViewController(engine: self.flutterEngine!, nibName: nil, bundle: nil)
      window = UIWindow(frame: UIScreen.main.bounds)
      window?.rootViewController = flutterViewController
      window?.makeKeyAndVisible()

      // let vc = ToFlutterPage()
      // window = UIWindow(frame: UIScreen.main.bounds)
      // window?.rootViewController = vc
      // window?.makeKeyAndVisible()
    
    // 注册通道
    

    let methodChannel = FlutterMethodChannel(
      name: "com.eason.nebula/permission",
      binaryMessenger: flutterViewController.binaryMessenger)
    methodChannel.setMethodCallHandler {
      [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) in
      guard let self = self else { return }
      switch call.method {
      case "getBatteryLevel":
        self.receiveBatteryLevel(result: result)
      case "requestPermission":
        self.requestPermission(arguments: call.arguments, result: result)
      case "getStorageAvailable":
        let freeSpace = self.getAvailableDiskSpace()
        if freeSpace >= 0 {
          result(freeSpace)
        } else {
          result(
            FlutterError(code: "UNAVAILABLE", message: "Storage info not available", details: nil))
        }
      default:
        result(FlutterMethodNotImplemented)
      }
    }
    // 定义电池电量变化事件处理器（已有）
    let batteryStreamHandler = BatteryStreamHandler()

    // 电池电量事件通道
    let batteryEventChannel = FlutterEventChannel(
      name: "com.eason.nebula/batteryStream", binaryMessenger: flutterViewController.binaryMessenger
    )
    batteryEventChannel.setStreamHandler(batteryStreamHandler)

    // 网络状态事件通道
    let networkEventChannel = FlutterEventChannel(
      name: "com.eason.nebula/networkStream", binaryMessenger: flutterViewController.binaryMessenger
    )
    networkEventChannel.setStreamHandler(NetworkStatusStreamHandler())

    // 音量状态事件通道
    let volumeEventChannel = FlutterEventChannel(
      name: "com.eason.nebula/volumeStream", binaryMessenger: flutterViewController.binaryMessenger)
    volumeEventChannel.setStreamHandler(VolumeStreamHandler())

    let nativeChannel = FlutterMethodChannel(
      name: "com.eason.nebula/native",
      binaryMessenger: flutterViewController.binaryMessenger)
    nativeChannel.setMethodCallHandler { [weak self] (call, result) in
      guard let self = self else { return }
      if call.method == "navigateToNativePage" {
        self.navigateToNativePage()
        result("success")
      } else {
        result(FlutterMethodNotImplemented)
      }
    }
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
  private func receiveBatteryLevel(result: FlutterResult) {
    let batteryLevel = getBatteryLevel()
    if batteryLevel >= 0 {
      result(batteryLevel)
    } else {
      result(
        FlutterError(
          code: "UNAVAILABLE",
          message: "Battery level not available.",
          details: nil))
    }
  }
  // getBatteryLevel 增加个方法给flutter 调用显示电量
  @objc func getBatteryLevel() -> Int {
    let device = UIDevice.current
    device.isBatteryMonitoringEnabled = true
    let batteryLevel = device.batteryLevel
    debugPrint("电量值: \(batteryLevel)")  // 打印电量值
    return Int(batteryLevel * 100)  // 返回百分比
  }
  private func requestPermission(arguments: Any?, result: @escaping FlutterResult) {
    guard let args = arguments as? [String: Any],
      let type = args["type"] as? String
    else {
      result(
        FlutterError(code: "INVALID_ARGUMENT", message: "Missing or invalid 'type'", details: nil))
      return
    }

    switch type {
    case "microphone":
      AVAudioSession.sharedInstance().requestRecordPermission { granted in
        DispatchQueue.main.async {
          result(granted)
        }
      }

    case "camera":
      AVCaptureDevice.requestAccess(for: .video) { granted in
        DispatchQueue.main.async {
          result(granted)
        }
      }

    case "location":
      locationManager.requestWhenInUseAuthorization()
      DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        let status = CLLocationManager.authorizationStatus()
        result(status == .authorizedWhenInUse || status == .authorizedAlways)
      }

    case "notification":
      UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) {
        granted, _ in
        DispatchQueue.main.async {
          result(granted)
        }
      }

    case "photos":
      PHPhotoLibrary.requestAuthorization { status in
        DispatchQueue.main.async {
          result(status == .authorized || status == .limited)
        }
      }

    case "contacts":
      let store = CNContactStore()
      store.requestAccess(for: .contacts) { granted, _ in
        DispatchQueue.main.async {
          result(granted)
        }
      }

    case "calendar":
      eventStore.requestAccess(to: .event) { granted, _ in
        DispatchQueue.main.async {
          result(granted)
        }
      }

    case "clipboard":
      // 读取剪贴板内容视为已授权，始终返回 true
      result(true)

    case "bluetooth":
      let status = CBCentralManager.authorization
      result(status == .allowedAlways)

    case "storage":
      // iOS 无需权限即可访问 App 沙盒内存储，默认返回 true
      let freeSpace = getAvailableDiskSpace()
      if freeSpace >= 0 {
        result(freeSpace)
      } else {
        result(
          FlutterError(code: "UNAVAILABLE", message: "Storage info not available", details: nil))
      }
    case "battery":
      // 获取电池电量
      let batteryLevel = getBatteryLevel()
      if batteryLevel >= 0 {
        result(batteryLevel)
      } else {
        result(
          FlutterError(code: "UNAVAILABLE", message: "Battery level not available", details: nil))
      }
    case "volume":
      let session = AVAudioSession.sharedInstance()
      try? session.setActive(true)
      let volume = session.outputVolume
      result(volume)
    default:
      result(
        FlutterError(
          code: "INVALID_TYPE", message: "Unsupported permission type: \(type)", details: nil))
    }
  }
}

extension AppDelegate {
  private func navigateToNativePage() {
    let nativeVC = UIViewController()
    nativeVC.view.backgroundColor = .white

    let label = UILabel()
    label.text = "这是一个原生页面"
    label.textAlignment = .center
    label.font = UIFont.systemFont(ofSize: 24)
    label.translatesAutoresizingMaskIntoConstraints = false

    nativeVC.view.addSubview(label)
    NSLayoutConstraint.activate([
      label.centerXAnchor.constraint(equalTo: nativeVC.view.centerXAnchor),
      label.centerYAnchor.constraint(equalTo: nativeVC.view.centerYAnchor),
    ])

    // 确保从主线程触发
    DispatchQueue.main.async {
      print("rootViewController = \(String(describing: self.window?.rootViewController))")
      if let nav = self.window?.rootViewController as? UINavigationController {
        nav.pushViewController(nativeVC, animated: true)
      } else if let rootVC = self.window?.rootViewController {
        // fallback: present 模态方式
        rootVC.present(nativeVC, animated: true, completion: nil)
      }
    }
  }
  private func getNetworkStatus() -> String {
    var zeroAddress = sockaddr_in()
    zeroAddress.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
    zeroAddress.sin_family = sa_family_t(AF_INET)

    guard
      let defaultRouteReachability = withUnsafePointer(
        to: &zeroAddress,
        {
          $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { zeroSockAddress in
            SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
          }
        })
    else {
      return "unknown"
    }

    var flags = SCNetworkReachabilityFlags()
    if !SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) {
      return "unknown"
    }

    if !flags.contains(.reachable) {
      return "none"  // 无网络
    } else if flags.contains(.isWWAN) {
      return "cellular"  // 蜂窝网络
    } else {
      return "wifi"  // WiFi
    }
  }

  private func getAvailableDiskSpace() -> Int64 {
    do {
      let attrs = try FileManager.default.attributesOfFileSystem(forPath: NSHomeDirectory())
      if let freeSize = attrs[.systemFreeSize] as? NSNumber {
        return freeSize.int64Value
      }
    } catch {
      print("获取可用磁盘空间失败: \(error)")
    }
    return -1
  }
}
class BatteryStreamHandler: NSObject, FlutterStreamHandler {
  private var eventSink: FlutterEventSink?
  private var timer: Timer?

  func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink)
    -> FlutterError?
  {
    self.eventSink = events
    startSendingBatteryLevel()
    return nil
  }

  func onCancel(withArguments arguments: Any?) -> FlutterError? {
    stopSendingBatteryLevel()
    return nil
  }

  private func startSendingBatteryLevel() {
    timer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { _ in
      let level = UIDevice.current.batteryLevel
      if level >= 0 {
        self.eventSink?(["batteryLevel": Int(level * 100)])
      } else {
        self.eventSink?(
          FlutterError(code: "UNAVAILABLE", message: "Battery level unavailable", details: nil))
      }
    }
    UIDevice.current.isBatteryMonitoringEnabled = true
  }

  private func stopSendingBatteryLevel() {
    timer?.invalidate()
    timer = nil
    UIDevice.current.isBatteryMonitoringEnabled = false
  }
}

class NetworkStatusStreamHandler: NSObject, FlutterStreamHandler {
  private var eventSink: FlutterEventSink?
  private var monitor: NWPathMonitor?
  private let queue = DispatchQueue(label: "NetworkMonitor")

  func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink)
    -> FlutterError?
  {
    self.eventSink = events
    monitor = NWPathMonitor()
    monitor?.pathUpdateHandler = { path in
      var status = "unknown"
      if path.status == .satisfied {
        if path.usesInterfaceType(.wifi) {
          status = "wifi"
        } else if path.usesInterfaceType(.cellular) {
          status = "cellular"
        } else {
          status = "other"
        }
      } else {
        status = "none"
      }
      self.eventSink?(status)
    }
    monitor?.start(queue: queue)
    return nil
  }

  func onCancel(withArguments arguments: Any?) -> FlutterError? {
    monitor?.cancel()
    monitor = nil
    eventSink = nil
    return nil
  }
}

// 音量状态事件流处理器
class VolumeStreamHandler: NSObject, FlutterStreamHandler {
  private var eventSink: FlutterEventSink?
  private var observation: NSKeyValueObservation?

  func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink)
    -> FlutterError?
  {
    self.eventSink = events

    let session = AVAudioSession.sharedInstance()
    try? session.setActive(true)
    self.eventSink?(session.outputVolume)

    observation = session.observe(\.outputVolume, options: [.new]) { session, change in
      if let newVolume = change.newValue {
        self.eventSink?(newVolume)
      }
    }

    return nil
  }

  func onCancel(withArguments arguments: Any?) -> FlutterError? {
    observation?.invalidate()
    observation = nil
    eventSink = nil
    return nil
  }
}
